#include "tthread.h"
#include <QtNetwork>
#include <QtGui>
#include "parser.h"
#include <iostream>
#include "tnotify.h"
#include "singleton.h"

TThread::TThread(QObject *parent) :
    QObject(parent)
{

}

TThread::TThread(QUrl url, QString threadName, QObject *parent) :
    QObject(parent),
    URL(url),
    timer (new QTimer()),
    nm (&Singleton<TNetworkManager>::Instance())
{
    //Set initial state
    state = new TState(TState::PENDING);
    QObject::connect(state, SIGNAL(isChanged()), this, SIGNAL(isChanged()));
    //Tune autoupdate timer
    timer->setInterval(10000);
    QObject::connect(timer, SIGNAL(timeout()), this, SLOT(checkThread()));

    QRegExp regexp("http://dobrochan.ru/(mad|lor|b|vg)/res/([0-9]*).xhtml");
    regexp.indexIn(URL.toString());
    threadBoard = regexp.cap(1);
    threadNumber = regexp.cap(2);
    QString mahurl(URL.toString());
    mahurl.chop(5);
    mahurl.append("json");
    jsonURL = QUrl(mahurl);
    QNetworkRequest request(jsonURL);
    //do it only to fetch thread name
    if(threadName.isNull()){
	std::cout << "Begin fetching information about thread" << std::endl;
	QNetworkReply* reply = nm->get2(request);

	QEventLoop loop;
	QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
	loop.exec();
	std::cout << "End fetching information about thread" << std::endl;

	if (reply->error() == QNetworkReply::NoError){
	    QString data(reply->readAll());
	    if (threadName.isNull()){
		if(parser::getTitleFromReply(data) != QString("")){
		    setName(parser::getTitleFromReply(data));
		}else{
		    setName("Cannot fetch name.");
		}
	    }else{
		setName(threadName);
	    }
	    lastReply = fetchLastPost(data);
	}
    }else{
	setName(threadName);
    }
    std::cout << "Thread name is " << threadName.toStdString() << std::endl;

    emit isChanged();
}

void TThread::setThreadNumber(QString number){
    threadNumber = number;
    emit isChanged();
}

QString TThread::getThreadNumber(void){
    return threadNumber;
}

void TThread::setThreadBoard(QString board){
    threadBoard = board;
    emit isChanged();
}

QString TThread::getThreadBoard(void){
    return threadBoard;
}

void TThread::setURL(QUrl url){
    URL = url;
    emit isChanged();
}

QUrl TThread::getURL(void){
    return URL;
}

void TThread::setState(int stateNum){
    state->setStateInt(stateNum);
}

QString TThread::getState(void){
    return state->getState();
}

QColor TThread::getColor(void){
    return state->getColor();
}

void TThread::setName(QString Name){
    name = Name;
    emit isChanged();
}

QString TThread::getName(void){
    return name;
}

QString TThread::fetchLastPost(void){
    QString appended = QString(threadBoard).append("/").append(threadNumber).append("/last.json?count=1");
    std::cout << appended.toStdString() <<std::endl;
    QNetworkReply* reply = nm->get2(QNetworkRequest(QUrl(QString("http://dobrochan.ru/api/thread/").append(appended))));
    QEventLoop loop;
    QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
    loop.exec();
    QString data = reply->readAll();
    std::cout << data.toStdString() << std::endl;
    lastModified = reply->header(QNetworkRequest::LastModifiedHeader).toDateTime().addSecs(1).toString("ddd, d MMM yyyy hh:mm:ss").append(" GMT");
    std::cout << lastModified.toStdString() << std::endl;
    return fetchLastPost(data);
}

QString TThread::fetchLastPost(QString data){
    QRegExp lastPostExp("\"display_id\":\\s(\\d*)");
    lastPostExp.lastIndexIn(data);
    std::cout <<"Last Post: "<< lastPostExp.cap(1).toStdString() <<std::endl;
    return lastPostExp.cap(1);
}

QString TThread::fetchLastModified(QString data){
    QRegExp lastModifiedExp("\"last_modified\":\\s\"([\\d- :]*)\"");
    lastModifiedExp.lastIndexIn(data);
    std::cout <<"Last Modified: "<< lastModifiedExp.cap(1).toStdString() <<std::endl;
    return lastModifiedExp.cap(1);
}

void TThread::startWatch(void){
    lastReply = fetchLastPost();
    this->timer->start();
    this->setState(TState::WATCHING);
}

void TThread::checkThread(void){
    QUrl requestUrl(QString("http://dobrochan.ru/api/thread/new/").append(threadBoard).append("/").append(threadNumber).append(".json?last_post=").append(lastReply));
    QNetworkRequest request = QNetworkRequest(requestUrl);
    request.setRawHeader("If-Modified-Since", lastModified.toAscii());
    QNetworkReply* reply = nm->get2(request);

    QEventLoop loop;
    QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
    loop.exec();

    QString data(reply->readAll());
    std::cout << data.toStdString() << std::endl;
    //std::cout << requestUrl.toString().toStdString() << std::endl;
    QRegExp messageExp("\"message\":\\s\"([^\"]*)\"");
    int pos = 0;
    int i = 0;

    std::cout << "Start parsing thread." << std::endl;
    while((pos = messageExp.indexIn(data, pos)) != -1 and i < 3){
        std::cout << "Parse number: " << i+1 << " Found message at: " << pos <<std::endl;
        QString message = parser::getMessageFromReply(data);
        data.replace(messageExp, "");
        TNotify* notify = &Singleton<TNotify>::Instance();
        notify->newNotify(name, message);
        lastReply = fetchLastPost(data);
        std::cout << "Message: " <<std::endl;
        std::cout << message.toStdString() <<std::endl;
        i++;
    }
}

void TThread::stopWatch(void){
    this->timer->stop();
    this->setState(TState::STOP);
    std::cout << "Thread \"" << name.toStdString() << "\" stopped." << std::endl;
}
